﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class DomainExpert
    {
        public static List<string> docs_For_Expert { get; set; } // all the docs (from all the clusters) which selected by random

        public DomainExpert()
        {
            docs_For_Expert = new List<string>();
        }

        /// <summary>
        /// the function got all the clusters and choose from each cluster the same number of docs.
        /// </summary>
        /// <param name="allClusters"></param>
        /// <param name="numOfDocsFromEachCluster"></param>
        /// <returns></returns>
        public Dictionary<string,int> SelectRandomDocumentsFromClusters(Dictionary<int, List<string>> allClusters, int numOfDocsFromEachCluster)
        {
            Dictionary<string, int> chosen_Docs = new Dictionary<string, int>();
            int numOfDocsForExpert = 0; //count the number of docs until reach the number which selected by the user to be chosen for each cluster.
            Random r = new Random();
            int randomNum;
            int fileWereNotCreated = 0; // if there is cluster with less items than the number to choose from it, count it.

            foreach(KeyValuePair<int, List<string>> item in allClusters)
            {
                List<string> docsInCluster = item.Value;

                if (numOfDocsFromEachCluster > docsInCluster.Count) // the user want to choose a number that greater than the number of the docs in the cluster
                    {
                        fileWereNotCreated++;
                        Console.WriteLine("There are *" + fileWereNotCreated + "* clusters which have less documents than the number who inserted. therefore they won't created.");
                        continue; // don't choose from this cluster //TODO
                    }
 
                    while (numOfDocsForExpert < numOfDocsFromEachCluster)
                    {
                        randomNum = r.Next(0, docsInCluster.Count);
                        string docName = docsInCluster[randomNum];
                        if (!chosen_Docs.ContainsKey(docName)) // for case that doc was already drown
                        {
                            chosen_Docs.Add(docName, item.Key); // list with the docs were drown <docName, cluster>
                            docs_For_Expert.Add(docName); //list with all the docs were drown
                            numOfDocsForExpert++;
                        }
                        
                    }
                    numOfDocsForExpert = 0;
                    continue;
            }
            return chosen_Docs;
        }

        /// <summary>
        /// from all the files were drown, makes random pairs for the expert.
        /// </summary>
        /// <param name="chosenDocs"></param>
        /// <param name="numOfPairs"></param>
        /// <returns></returns>
        public Dictionary<KeyValuePair<string, string>, double> CreatePairsOfDocs(Dictionary<string, int> chosenDocs, int numOfPairs)
        {
            Dictionary<string, List<string>> compares = new Dictionary<string, List<string>>(); // store the pairs were already chosen
            Dictionary<KeyValuePair<string, string>, double> pairs_For_Expert = new Dictionary<KeyValuePair<string, string>, double>(); // store the pairs
            Random r = new Random();
            int allPossibleCombinations = ((docs_For_Expert.Count + 1) * docs_For_Expert.Count / 2) - docs_For_Expert.Count ; // calc all the possible combinations to create pairs

            if (numOfPairs > allPossibleCombinations) // if the number of pairs the user wish to create is larger than the possible
            {
                Console.WriteLine("you are try to choose documents for expert more than all the possible combinations");
                Console.WriteLine("choose new number which is smaller or equal than: " + allPossibleCombinations);
                numOfPairs = int.Parse(Console.ReadLine());
            }
            int combinationNum = 0;

            while (combinationNum < numOfPairs)
            {
                int num_1 = r.Next(0, docs_For_Expert.Count);
                string doc_1 = docs_For_Expert[num_1]; // drow the first doc
                int num_2 = r.Next(0, docs_For_Expert.Count);
                string doc_2 = docs_For_Expert[num_2]; // drow the second doc
                bool wasChosen_1 = false;
                bool wasChosen_2 = false;

                if (num_1 != num_2) // cannot drill the same doc
                {
                    if (!compares.ContainsKey(doc_1))
                        compares.Add(doc_1, new List<string>());
                    if (!compares[doc_1].Contains(doc_2))
                    {
                        compares[doc_1].Add(doc_2);
                        wasChosen_1 = true;
                    }
                    if (!compares.ContainsKey(doc_2))
                        compares.Add(doc_2, new List<string>());
                    if (!compares[doc_2].Contains(doc_1))
                    {
                        compares[doc_2].Add(doc_1);
                        wasChosen_2 = true;
                    }

                    if (wasChosen_1 && wasChosen_2) //only if the pair weren't selected already.
                    {
                        pairs_For_Expert.Add(new KeyValuePair<string, string>(doc_1, doc_2), 0);
                        combinationNum++;
                    }
                    wasChosen_1 = false;
                    wasChosen_2 = false;
                }

            }
            return pairs_For_Expert;
        }

    }
}
